package com.yanqu.road.entity.specialcookboy;


import com.yanqu.road.utils.date.DateHelper;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class ShareCodeUtil {

    /** 自定义进制(0,1没有加入,容易与o,l混淆) */

    private static final char[] r=new char[]{'Q', 'W', 'E', '8', 'A', 'S', '2', 'D', 'Z', 'X', '9', 'C', '7', 'P', '5', 'I', 'K', '3', 'M', 'J', 'U', 'F', 'R', '4', 'V', 'Y', 'L', 'T', 'N', '6', 'B', 'G', 'H'};

    /** (不能与自定义进制有重复) */

    private static final char b='O';

    /** 进制长度 */

    private static final int binLen=r.length;

    /** 序列最小长度 */

    private static final int s=6;

    /**

     * 根据ID生成六位随机码
     * @param id ID
     * @return 随机码
     */
    public static String toSerialCode(long id) {

        char[] buf=new char[32];

        int charPos=32;

        while((id / binLen) > 0) {
            int ind=(int)(id % binLen);
            buf[--charPos]=r[ind];
            id /= binLen;
        }
        buf[--charPos]=r[(int)(id % binLen)];
        // System.out.println(num + "-->" + num % binLen);
        String str=new String(buf, charPos, (32 - charPos));
        // 不够长度的自动随机补全
        if(str.length() < s) {
            StringBuilder sb=new StringBuilder();
            sb.append(b);
            Random rnd=new Random();
            for(int i=1; i < s - str.length(); i++) {
                sb.append(r[rnd.nextInt(binLen)]);
            }
            str+=sb.toString();
        }

        return str;

    }

    public static long codeToId(String code) {

        char chs[]=code.toCharArray();
        long res=0L;
        for(int i=0; i < chs.length; i++) {
            int ind=0;
            for(int j=0; j < binLen; j++) {
                if(chs[i] == r[j]) {
                    ind=j;
                    break;
                }
            }
            if(chs[i] == b) {
                break;
            }
            if(i > 0) {
                res=res * binLen + ind;
            } else {
                res=ind;
            }
        }
        return res;
    }
    //通过对sharecode最后一位决定不同的加密方式
    public static String replaceShareCode(String shareCode) {
        char[] chars = shareCode.toCharArray();
        int length = chars.length;
        char lastChar = chars[length - 1];
        int lastInt = lastChar;
        int i = lastInt % 10;
        String code = changSite(chars,i);

        return code;
    }


    /**
     * 双向 换位置 不重复 后面要改可以改成可重复 单向每个字符加减数字
     * @param chars
     * @param type
     * @return
     */
    public static String changSite(char[] chars,int type){
        if (type == 0){
            return new String(chars);
        }else if (type == 1){
            char a = chars[0];
            chars[0] = chars[8];
            chars[8] = a;

            char b = chars[2];
            chars[2] = chars[5];
            chars[5] = b;

            char c = chars[1];
            chars[1] = chars[4];
            chars[4] = c;

            char d = chars[3];
            chars[3] = chars[6];
            chars[6] = d;
            return new String(chars);
        }else if (type == 2){
            char a = chars[7];
            chars[7] = chars[8];
            chars[8] = a;

            char b = chars[5];
            chars[5] = chars[4];
            chars[4] = b;

            char c = chars[0];
            chars[0] = chars[1];
            chars[1] = c;

            char d = chars[2];
            chars[2] = chars[3];
            chars[3] = d;

            return new String(chars);
        } else if (type==3){
            char a = chars[2];
            chars[2] = chars[6];
            chars[6] = a;

            char b = chars[5];
            chars[5] = chars[1];
            chars[1] = b;

            char c = chars[7];
            chars[7] = chars[3];
            chars[3] = c;

            char d = chars[4];
            chars[4] = chars[8];
            chars[8] = d;


            return new String(chars);
        }else if (type==4){
            char a = chars[1];
            chars[1] = chars[2];
            chars[2] = a;

            char b = chars[0];
            chars[0] = chars[6];
            chars[6] = b;

            char c = chars[3];
            chars[3] = chars[7];
            chars[7] = c;

            char d = chars[5];
            chars[5] = chars[4];
            chars[4] = d;


            return new String(chars);
        }else if (type==5){
            char a = chars[0];
            chars[0] = chars[8];
            chars[8] = a;

            char b = chars[6];
            chars[6] = chars[3];
            chars[3] = b;

            char c = chars[7];
            chars[7] = chars[2];
            chars[2] = c;

            char d = chars[4];
            chars[4] = chars[1];
            chars[1] = d;


            return new String(chars);
        }else if (type==6){
            char a = chars[7];
            chars[7] = chars[3];
            chars[3] = a;

            char b = chars[6];
            chars[6] = chars[1];
            chars[1] = b;

            char c = chars[5];
            chars[5] = chars[2];
            chars[2] = c;

            char d = chars[4];
            chars[4] = chars[0];
            chars[0] = d;


            return new String(chars);
        }else if (type==7){
            char a = chars[5];
            chars[5] = chars[1];
            chars[1] = a;

            char b = chars[4];
            chars[4] = chars[8];
            chars[8] = b;

            char c = chars[3];
            chars[3] = chars[7];
            chars[7] = c;

            char d = chars[6];
            chars[6] = chars[0];
            chars[0] = d;


            return new String(chars);
        }else if (type==8){
            char a = chars[6];
            chars[6] = chars[0];
            chars[0] = a;

            char b = chars[4];
            chars[4] = chars[5];
            chars[5] = b;

            char c = chars[8];
            chars[8] = chars[3];
            chars[3] = c;

            char d = chars[1];
            chars[1] = chars[2];
            chars[2] = d;


            return new String(chars);
        }else if (type==9){
            char a = chars[5];
            chars[5] = chars[7];
            chars[7] = a;

            char b = chars[2];
            chars[2] = chars[6];
            chars[6] = b;

            char c = chars[4];
            chars[4] = chars[0];
            chars[0] = c;

            char d = chars[1];
            chars[1] = chars[3];
            chars[3] = d;


            return new String(chars);
        }

        return new String(chars);
    }

    /**
     * 生成分享码
     * @param id
     * @param now
     * @return
     */

    public static String generateShareCode(long id,long now) {
        long tmpId = id + now;
        String code = toSerialCode(tmpId);
        String s1 = replaceShareCode(code);
        return s1;
    }

    /**
     * 解码分享码
     */

    public static long decodeShareCode(String code){
        String s1 = replaceShareCode(code);
        long l = codeToId(s1);
        long userId = l - DateHelper.getTodayZeroTimeStamp();
        return userId;
    }

    public static boolean checkStringAllInDigits(String str) {
        if (str.isEmpty()) {
            return false;
        }
        String digitsStr = String.valueOf(r);
        char[] chars = str.toCharArray();
        for (char aChar : chars) {
            if (digitsStr.indexOf(aChar) == -1) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        String s = generateShareCode(221000080000026L, DateHelper.getTodayZeroTimeStamp());
        System.out.println(s);

        long l = decodeShareCode(s);
        System.out.println(l);

    }


}
